#include <amxmodx>
#include <items>
#include <engine>
#include <cstrike>
#include <fakemeta>
#include <fun>

#define MAXMINES		3
#define MINE_DAMAGE		20
#define MINE_HEALTH		1000
#define MINE_INT_TEAM		EV_INT_iuser1
#define MINE_OWNER		EV_INT_iuser3
#define DMG_BULLET		(1<<1)

new PLUGIN_NAME[] 	= "UM Item: Laser Mine"
new PLUGIN_AUTHOR[] 	= "Cheap_Suit"
new PLUGIN_VERSION[] 	= "1.1"

new Float:Delay[33]
new g_PlayerMines[33]
new boom, beam
new bool:g_lasermine[33]
new g_msgDeathMsg
new g_msgScoreInfo
new g_msgDamage
new bool:g_Dropped[33]

public plugin_init() 
{
	register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
	register_item("Laser Mine", "Hold out your knife and press e to plant", 3900)
	
	register_think("lasermine","Lasermine_Think")
	register_event("DeathMsg", "Event_DeathMsg", "a")
	register_event("ResetHUD", "Event_ResetHUD", "be")
	register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_will_restart_in") 
	register_event("SendAudio", "Event_RoundEnd", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw")

	g_msgDeathMsg = get_user_msgid("DeathMsg")
	g_msgScoreInfo = get_user_msgid("ScoreInfo")
	g_msgDamage = get_user_msgid("Damage")
}

public plugin_precache() 
{
	precache_sound("weapons/mine_deploy.wav")
	precache_sound("weapons/mine_charge.wav")
	precache_sound("weapons/mine_activate.wav")
	precache_sound("debris/beamstart9.wav")
	precache_model("models/v_tripmine.mdl")
	beam = precache_model("sprites/laserbeam.spr")
	boom = precache_model("sprites/zerogxplode.spr")
}

public Event_RoundEnd() {
	set_task(2.0, "remove_mines")
}

public Event_GameRestart()
{
	new Float:fRestartCvar = get_cvar_float("sv_restart")
	set_task((fRestartCvar - 0.5), "Event_RoundEnd")	
}

public client_connect(id) 
{
	g_lasermine[id] = false
	g_PlayerMines[id] = 0
}

public Event_DeathMsg() 
{
	g_PlayerMines[read_data(2)] = 0
	g_Dropped[read_data(2)] = false
}

public Event_ResetHUD(id)
{
	if(g_lasermine[id]) 
	{
		g_Dropped[id] = false
		g_PlayerMines[id] = MAXMINES
	}
}

public Enable_Item(id) 
{
	if(g_Dropped[id]) {
		g_PlayerMines[id]  = 0
	} else {
		g_PlayerMines[id] = MAXMINES
	}
	g_lasermine[id] = true
}

public Disable_Item(id) 
{
	g_lasermine[id] = false
	g_Dropped[id] = true
}

public client_PreThink(id)
{
	if(!is_user_connected(id) || !is_user_alive(id)) {
		return PLUGIN_CONTINUE
	}
	
	if(!g_lasermine[id]) {
		return PLUGIN_CONTINUE
	}
	
	new temp[2], weapon = get_user_weapon(id, temp[0], temp[1])
	if(weapon == CSW_KNIFE)
	{
		if(get_user_button(id) & IN_USE)
		{
			if((Delay[id] + 1.3) < get_gametime())
			{
				if(g_PlayerMines[id] < 1) {
					client_print(id, print_chat, "No more mines")
				} else {
					Create_Mine(id)
				}
				Delay[id] = get_gametime()
			}
		}
	}
	return PLUGIN_CONTINUE
}

public remove_mines()
{
	new ent = find_ent_by_class(-1, "lasermine")
	while(ent) 
	{
		remove_entity(ent)
		ent = find_ent_by_class(ent, "lasermine")
	}
}

Create_Mine(id)
{
	new Mine = create_entity("info_target")
	if(is_valid_ent(Mine))  
	{
		entity_set_string(Mine, EV_SZ_classname, "lasermine")
		entity_set_int(Mine, EV_INT_movetype, MOVETYPE_FLY)
		entity_set_int(Mine, EV_INT_solid, SOLID_NOT)
		entity_set_model(Mine, "models/v_tripmine.mdl")
	
		entity_set_float(Mine, EV_FL_frame, 0.0)
		entity_set_int(Mine, EV_INT_body, 3)
		entity_set_int(Mine, EV_INT_sequence, 7)
		entity_set_float(Mine, EV_FL_framerate, 0.0)

		entity_set_float(Mine, EV_FL_takedamage, 1.0)
		entity_set_float(Mine, EV_FL_dmg, 100.0)
		entity_set_float(Mine, EV_FL_health, float(MINE_HEALTH))

		entity_set_int(Mine, EV_INT_iuser2, 0)

		new Float:MinBox[3] = {-8.0, -8.0, -8.0}
		new Float:MaxBox[3] = {8.0, 8.0, 8.0}
		entity_set_size(Mine, MinBox, MaxBox)

		new Float:vOrigin[3]
		entity_get_vector(id, EV_VEC_origin, vOrigin)
		
		new Float:flVelocity[3]
		VelocityByAim(id, 64, flVelocity)

		new Float:vTraceEnd[3]
		vTraceEnd[0] = flVelocity[0] + vOrigin[0]
		vTraceEnd[1] = flVelocity[1] + vOrigin[1]
		vTraceEnd[2] = flVelocity[2] + vOrigin[2]

		new Float:vTraceResult[3]
		trace_line(id, vOrigin, vTraceEnd, vTraceResult)

		new Float:vNormal[3]
		if(trace_normal(id, vOrigin, vTraceEnd, vNormal) < 1)
		{
			remove_entity(Mine)
			client_print(id, print_chat, "You must plant the Laser mine on a wall")
			return PLUGIN_HANDLED_MAIN
		}
		
		new Float:vNewOrigin[3]
		
		vNewOrigin[0] = vTraceResult[0] + (vNormal[0] * 8.0)
		vNewOrigin[1] = vTraceResult[1] + (vNormal[1] * 8.0)
		vNewOrigin[2] = vTraceResult[2] + (vNormal[2] * 8.0)
		
		entity_set_origin(Mine, vNewOrigin)
		
		new Float:vMineAngles[3]
		vector_to_angle(vNormal, vMineAngles)	
		entity_set_vector(Mine, EV_VEC_angles, vMineAngles)
		
		new Float:vBeamEnd[3]
		
		vBeamEnd[0] = vNewOrigin[0] + (vNormal[0] * 8192)
		vBeamEnd[1] = vNewOrigin[1] + (vNormal[1] * 8192)
		vBeamEnd[2] = vNewOrigin[2] + (vNormal[2] * 8192)
		
		new Float:vTracedBeamEnd[3]
		trace_line(-1, vNewOrigin, vBeamEnd, vTracedBeamEnd)
		entity_set_vector(Mine, EV_VEC_vuser1, vTracedBeamEnd)
		
		emit_sound(Mine, CHAN_WEAPON, "weapons/mine_deploy.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
		emit_sound(Mine, CHAN_ITEM, "weapons/mine_charge.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
		
		new PlayerTeam = get_user_team(id)
		entity_set_int(Mine, MINE_INT_TEAM, PlayerTeam)
		entity_set_int(Mine, MINE_OWNER, id)
		
		client_print(id, print_chat, "Planted mine")
		client_print(id, print_chat, "%d mines left", g_PlayerMines[id] - 1)
		g_PlayerMines[id] -= 1
	
		new param[1]
		param[0] = Mine
		set_task(3.5, "Mine_Activate", 0, param, 1)	
	}
	return PLUGIN_HANDLED_MAIN
}

public Mine_Activate(param[]) 
{
	new Mine = param[0]
	if(is_valid_ent(Mine)) 
	{
		entity_set_int(Mine, EV_INT_iuser2, 1)
		entity_set_int(Mine, EV_INT_solid, 2)
		entity_set_float(Mine, EV_FL_nextthink, halflife_time() + 0.01)
		emit_sound(Mine, CHAN_ITEM, "weapons/mine_activate.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
	}
}
	
public Lasermine_Think(Mine)
{
	if(is_valid_ent(Mine)) 
	{
		new TeamColor[3], MineTeam = entity_get_int(Mine, MINE_INT_TEAM)
		switch(MineTeam)
		{
			case 1:
			{
				TeamColor[0] = 255
				TeamColor[1] = 0
				TeamColor[2] = 0
			}
			case 2:
			{
				TeamColor[0] = 0
				TeamColor[1] = 0
				TeamColor[2] = 255
			}
		}
			
		new Float:vOrigin[3], Float:vEnd[3]
		entity_get_vector(Mine, EV_VEC_origin, vOrigin)
		entity_get_vector(Mine, EV_VEC_vuser1, vEnd)
		
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY) 
		write_byte(0)
		write_coord(floatround(vOrigin[0]))
		write_coord(floatround(vOrigin[1]))
		write_coord(floatround(vOrigin[2]))
		write_coord(floatround(vEnd[0]))
		write_coord(floatround(vEnd[1]))
		write_coord(floatround(vEnd[2]))
		write_short(beam)
		write_byte(0)
		write_byte(0)
		write_byte(3)
		write_byte(5)
		write_byte(0)
		write_byte(TeamColor[0])
		write_byte(TeamColor[1])
		write_byte(TeamColor[2])
		write_byte(255)
		write_byte(0)
		message_end()
		
		if(entity_get_int(Mine, EV_INT_iuser2) == 1) 
		{	
			if(entity_get_float(Mine, EV_FL_health) <= 500) {
				Detonate_Mine(Mine)
			}
			else
			{
				new Float:vOrigin[3], Float:vEnd[3]
				entity_get_vector(Mine, EV_VEC_origin, vOrigin)
				entity_get_vector(Mine, EV_VEC_vuser1, vEnd)	
					
				new Float:vTrace[3], id = trace_line(Mine, vOrigin, vEnd, vTrace)		
				if(is_user_connected(id) && is_user_alive(id)) 
				{	
					new bool:doDamage
					new VictimTeam = get_user_team(id)
					new MineTeam = entity_get_int(Mine, MINE_INT_TEAM)
					new FriendlyFire = get_cvar_num("mp_friendlyfire") 
					switch(FriendlyFire)
					{
						case 0:
						{
							if(VictimTeam != MineTeam) { 	
								doDamage = true
							} else {
								doDamage = false
							}
						}
						case 1:	doDamage = true
					}
								
					if(doDamage)
					{
						new VictimHealth = get_user_health(id) 
						new Damage = VictimHealth - MINE_DAMAGE	
					
						if(Damage <= 0) 
						{
							new MineOwner = entity_get_int(Mine, MINE_OWNER)
							Create_Kill(id, MineOwner, "Lasermine")
						}
						else
						{
							set_user_health(id, Damage)
								
							message_begin(MSG_ONE_UNRELIABLE, g_msgDamage, {0, 0, 0}, id) 
							write_byte(MINE_DAMAGE)
							write_byte(MINE_DAMAGE)
							write_long(DMG_BULLET)
							write_coord(floatround(vOrigin[0]))
							write_coord(floatround(vOrigin[1]))
							write_coord(floatround(vOrigin[2]))
							message_end()
						}
						emit_sound(id, CHAN_WEAPON, "debris/beamstart9.wav", 1.0, ATTN_NORM, 0, PITCH_NORM)
					}
				}
			}
		}
	}
	entity_set_float(Mine, EV_FL_nextthink, halflife_time() + 0.01)
}

Detonate_Mine(Mine) 
{
	new Float:vOrigin[3]
	entity_get_vector(Mine, EV_VEC_origin, vOrigin)

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(99)
	write_short(Mine)
	message_end()

	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(3)
	write_coord(floatround(vOrigin[0]))
	write_coord(floatround(vOrigin[1]))
	write_coord(floatround(vOrigin[2]))
	write_short(boom)
	write_byte(50)
	write_byte(15)
	write_byte(0)
	message_end()

	radius_damage(vOrigin, 1, 50)
	remove_entity(Mine)
	
	return PLUGIN_CONTINUE
}

Create_Kill(id, attacker, weaponDescription[]) 
{
	new FFon = get_cvar_num("mp_friendlyfire") 
	if(FFon && get_user_team(id) == get_user_team(attacker)) 
	{ 
		set_user_frags(attacker, get_user_frags(attacker) - 1) 
		client_print(attacker, print_center, "You killed a teammate") 
         
		new money = cs_get_user_money(attacker) 
		if(money != 0) cs_set_user_money(attacker, money - 150, 1) 
	} 
	else if(get_user_team(id) != get_user_team(attacker)) 
	{ 
		set_user_frags(attacker, get_user_frags(attacker) + 1) 
		new money = cs_get_user_money(attacker) 
         
		if(money < 16000) cs_set_user_money(attacker,money + 300,1) 
	} 
     
	logKill(attacker, id, weaponDescription) 
     
	//Kill the victim and block the messages 
	set_msg_block(g_msgDeathMsg,BLOCK_ONCE) 
	set_msg_block(g_msgScoreInfo,BLOCK_ONCE) 
	user_kill(id) 
	     
	//user_kill removes a frag, this gives it back 
	set_user_frags(id,get_user_frags(id) + 1) 
	     
	    //Replaced HUD death message 
	message_begin(MSG_ALL,g_msgDeathMsg,{0,0,0},0) 
	write_byte(attacker) 
	write_byte(id) 
	write_byte(0) 
	write_string(weaponDescription) 
	message_end() 
	     
	//Update killers scorboard with new info 
	message_begin(MSG_ALL,g_msgScoreInfo) 
	write_byte(attacker) 
	write_short(get_user_frags(attacker)) 
	write_short(get_user_deaths(attacker)) 
	write_short(0) 
	write_short(get_user_team(attacker)) 
	message_end() 
	     
	//Update victims scoreboard with correct info 
	message_begin(MSG_ALL,g_msgScoreInfo) 
	write_byte(id) 
	write_short(get_user_frags(id)) 
	write_short(get_user_deaths(id)) 
	write_short(0) 
	write_short(get_user_team(id)) 
	message_end()
} 

// ------- LOG KILL------------ 

public logKill(id, victim, weaponDescription[] ) 
{ 
	new namea[32],namev[32],authida[35],authidv[35],teama[16],teamv[16] 
     
	//Info On Attacker 
	get_user_name(id,namea,31) 
	get_user_team(id,teama,15) 
	get_user_authid(id,authida,34) 
     
	//Info On Victim 
	get_user_name(victim,namev,31) 
	get_user_team(victim,teamv,15) 
	get_user_authid(victim,authidv,34) 
     
	//Log This Kill 
	if( id != victim ) 
	{ 
		log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"", 
		namea,get_user_userid(id),authida,teama,namev,get_user_userid(victim),authidv,teamv, weaponDescription ) 
	} 
	else 
	{ 
		log_message("^"%s<%d><%s><%s>^" committed suicide with ^"%s^"", 
		namea,get_user_userid(id),authida,teama, weaponDescription ) 
	} 
} 
